package pogvue.datamodel;

import java.util.*;
import pogvue.io.*;

 public class GFF extends Sequence implements GFFI {
     private final Vector<SequenceFeature> feat;

     public GFF(String name, String sequence, int start, int end) {
 	super(name,sequence,start,end);
 		feat = new Vector<SequenceFeature>();
     }

    public Hashtable getScores() {
	if (feat.size() > 0) {
	    return ((SequenceFeature)feat.elementAt(0)).getScores();
	} else {
	    return null;
	}
    }
     public String getType() {
	if (feat.size() > 0) {
	    return ((SequenceFeature)feat.elementAt(0)).getType();
	} else {
	    return null;
	}
     }
    public void addFeature(SequenceFeature sf) {
    	feat.addElement(sf);
    }
    public Vector getFeatures() {
    	return feat;
    }
    
    public SequenceFeature getFeatureAt(int i) {
    	return feat.elementAt(i);
    }

    public Vector<SequenceFeature> overlaps(int start, int end) {
	Vector<SequenceFeature> out = new Vector<SequenceFeature>();
	
	for (int i = 0; i < feat.size(); i++) {
	    SequenceFeature sf = feat.elementAt(i);
	    
	    if (!(sf.getStart() > end || sf.getEnd() < start)) {
		out.addElement(sf);
	    }
	}
	return out;
    }

     public static Vector hashFeatures(Vector infeat, int offset, LinkedHashMap typeorder, boolean bump) {

	 Hashtable hash = new Hashtable();
	 Vector    feat = new Vector();		


	 // Hash the features into features

	 for (int i = 0; i < infeat.size(); i++) {
	     SequenceFeature sf    = (SequenceFeature)infeat.elementAt(i);
	     sf.setStart(sf.getStart()-offset);
	     sf.setEnd(sf.getEnd()-offset);
	     
	     if (hash.containsKey(sf.getType())) {
		 GFF tmp = (GFF)hash.get(sf.getType());
		 tmp.addFeature(sf);
	     } else  {
		 Vector tmp = new Vector();
		 tmp.addElement(sf);
		 GFF tmpg = new GFF(sf.getType(),"",1,2);
		 tmpg.addFeature(sf);
		 hash.put(sf.getType(),tmpg);
	     }
	 }
	 


	 // Start the output vector with known types
	 if (typeorder != null) {
	   Iterator pogit = typeorder.keySet().iterator();
	     
	   while (pogit.hasNext()) {
	     String next = (String)pogit.next();
	     System.out.println("Next is " + next);
	     if (hash.containsKey(next)) {
	       GFF tmp = (GFF)hash.get(next);
	       System.out.println("Adding " + tmp);
	       if (bump) {
		 Vector tmpvec = GFFFile.bumpGFF(tmp);
		 for (int i = 0; i < tmpvec.size(); i++) {
		   feat.addElement(tmpvec.elementAt(i));
		 }
	       } else {
		 feat.addElement((GFF)hash.get(next));
	       }
	     }
	   }
	 }
	 
	 // Add the remaining features
	 Enumeration pogen2 = hash.keys();
	 
	 while (pogen2.hasMoreElements()) {
	   String type = (String)pogen2.nextElement();
	   if (typeorder.keySet().contains(type) == false) {
	     
	     GFF tmp = (GFF)hash.get(type);
	     
	     if (bump) {
	       Vector tmpvec = GFFFile.bumpGFF(tmp);
	       for (int i = 0; i < tmpvec.size(); i++) {
		 feat.addElement(tmpvec.elementAt(i));
	       }
	     } else {
	       feat.addElement((GFF)hash.get(type));
	     }
	   }
	 }

	 return feat;
     }
	


   public static Hashtable hashHitFeatures(Vector feat) {

     Hashtable out = new Hashtable();

     for (int i = 0;i < feat.size(); i++) {

       SequenceFeature sf = (SequenceFeature)feat.elementAt(i);

       if (sf.getHitFeature() != null) {
	 
	 String name = sf.getHitFeature().getId();

	 if (!out.containsKey(name)) {
	   Vector tmp = new Vector();
	   tmp.addElement(sf);
	   out.put(name,tmp);
	 } else {
	   Vector tmp = (Vector)out.get(name);
	   tmp.addElement(sf);
	 }
       } else {
	 if (!out.containsKey("Single")) {
	   Vector tmp = new Vector();
	   tmp.addElement(sf);
	   out.put("Single",tmp);
	 } else {
	   Vector tmp = (Vector)out.get("Single");
	   tmp.addElement(sf);
	 }
	   
       }

     }

     Hashtable   out2 = new Hashtable();
     Enumeration en   = out.keys();

     while (en.hasMoreElements()) {

       String name = (String)en.nextElement();

       SequenceFeature sf = new SequenceFeature();
       sf.addFeatures((Vector)out.get(name));
       
       out2.put(name,sf);
     }

     return out2;
   }

   public void addFeatures(Vector feat) {
     for (int i = 0; i < feat.size(); i++) {
       addFeature((SequenceFeature)feat.elementAt(i));
     }
   }
   
 }











